use std::{ time, vec, sync::{ Arc, Mutex }};
use futures::future::{ join, join_all };
use async_std::task::sleep;
async fn connect_db() -> String {
    sleep(time::Duration::from_secs(1)).await;
    String::from("db")
}
async fn open_file() -> String {
    sleep(time::Duration::from_secs(1)).await;
    String::from("file")
}

async fn back_with_result() -> Result<String, ()> {
    Ok(String::from("Result"))
}

async fn select_db(input: &str) -> String {
    sleep(time::Duration::from_secs(1)).await;
    format!("select: {}", input)
}

async fn main_exe() {
    let (db, file) = join(connect_db(), open_file()).await;
    println!("{} {}", db, file);
    println!("{}", back_with_result().await.unwrap());
}

async fn get_cities() -> Vec<String> {
    let mut cities: Vec<String> = vec![
        String::from("Shanghai"),
        String::from("Beijing"),
        String::from("Guangzhou"),
        String::from("Shenzhen")
    ];

    let city_vec: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
    join_all(cities.into_iter().map(|city| {
        build_city(city_vec.clone(), city)
    })).await;
    return city_vec.lock().unwrap().clone();
}

async fn build_city(city_vec: Arc<Mutex<Vec<String>>>, city: String) {
    sleep(time::Duration::from_secs(1)).await;
    println!("super city build");
    city_vec.lock().unwrap().push(format!("china super city {}", city));
}

#[async_std::main]
async fn main() {
    let now = time::Instant::now();
    main_exe().await;
    println!("{:?}", now.elapsed());
    let users = vec!["teng", "tom", "lu"];
    let user_info = join_all(users.into_iter().map(|user| {
        select_db(&user)
    }).collect::<Vec<_>>()).await;
    println!("{:?}", user_info);
    println!("{:?}", now.elapsed());

    println!("{:?}", get_cities().await);
    println!("{:?}", now.elapsed());
}
